<?php

namespace App\Providers;

use App\Events\NewUserEvent;
use App\Listeners\InviteEventListener;
use App\Listeners\LoanEventSubscriber;
use App\Listeners\UserMoneySubscriber;
use App\Listeners\UserTicketSubscriber;
use App\Models\UserTicketLog;
use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Log;

class EventServiceProvider extends ServiceProvider
{
    /**
     * The event to listener mappings for the application.
     *
     * @var array<class-string, array<int, class-string>>
     */
    protected $listen = [
        NewUserEvent::class => [
            InviteEventListener::class,
        ],
    ];

    /**
     * The subscriber classes to register.
     *
     * @var array
     */
    protected $subscribe = [
        LoanEventSubscriber::class,
        UserMoneySubscriber::class,
        UserTicketSubscriber::class,
    ];

    /**
     * Register any events for your application.
     *
     * @return void
     */
    public function boot()
    {
        //记录sql执行日志
        DB::listen(function ($query) {

            // 生成环境不记录sql语句
            if (config('app.env') === 'production') return;

            // 将在sql中的函数中%符号转译, 最后再转译回来，防止使用DATE_FORMAT(`created_at`, '%Y-%m-%d')时报错
            $safeSql = str_replace(['%'], ['##_internal_##'], $query->sql);
            $resSql = vsprintf(
                str_replace(['?'], ['\'%s\''], $safeSql),
                //将所有的参数变为可以转换成字符串的形式
                array_map(function ($v) {
                    if (is_scalar($v)) return $v;
                    if (is_object($v)) {
                        if (method_exists($v, '__toString')) {
                            return (string) $v;
                        } else if ($v instanceof \DateTime === true) {
                            //oauth时，会出现此问题
                            return $v->format('Y-m-d H:i:s');
                        }
                    }
                }, $query->bindings)
            );


            /* @var $query \Illuminate\Database\Events\QueryExecuted */
            Log::debug(
                '[SQL EXEC]',
                [
                    "sql"  => str_replace(['##_internal_##'], ['%'], $resSql),
                    "time" => $query->time . ' milliseconds', //milliseconds
                ]
            );
        });
    }

    /**
     * Determine if events and listeners should be automatically discovered.
     *
     * @return bool
     */
    public function shouldDiscoverEvents()
    {
        return false;
    }
}
